﻿#region  
//=====================================================
// 文件名: EditorLoadReource                
// 创建者: #AuthorName#                
// 创建时间: #CreateTime#              	
// Email: #AuthorEmail#               
// 描述: 当前脚本的功能              
// 修改者列表: 修改者名字以及修改功能      
// 版权所有: #Copyright#                 
//======================================================
#endregion 



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FrameWork.Reource;
using FrameWork.AB;

namespace FrameWork.Reource
{
    public class EditorLoadReource : IResourceLoad
    {
        public override void Init(MonoBehaviour mono)
        {
            base.Init(mono);
            mMono.StartCoroutine(SyncLoad());
        }

        public override T LoadResource<T>(string path)
        {
            if (string.IsNullOrEmpty(path))
                return null;

            uint crc = CRC32.GetCRC32(path);

            ResourceItem _item = GetCacheResourceItem(crc, 1);

            if (_item != null)
                return _item.m_obj as T;

            T obj;
            _item = AssetBundleManager.Instance.FindRecourceItem(crc);

            if (_item == null)
            {
                Debug.LogError("There is no object to load:" + path);
                return null;
            }

            if (_item.m_obj != null)
            {
                obj = _item.m_obj as T;
            }
            else
            {
                obj = LoadAssetByEditor<T>(path);
            }

            CacheResource(path, ref _item, crc, obj);

            return obj;
        }

        IEnumerator SyncLoad()
        {
            long lastYiedTime = System.DateTime.Now.Ticks;
            while (true)
            {
                bool haveYield = false;
                for (int i = 0; i < (int)LoadResPriority.RES_NUM; i++)
                {
                    List<AsyncLoadResParm> loadingList = mLoadingAssetList[i];

                    if (loadingList.Count <= 0)
                    {
                        continue;
                    }
                    AsyncLoadResParm loadingItem = loadingList[0];
                    loadingList.RemoveAt(0);
                    List<AsyncCallBack> callBackList = loadingItem.mCallBackList;
                    Object obj = JudgeLoadType(loadingItem);


                    //Debug.LogErrorFormat("Load is :{0},A type of：{1}", obj, obj.GetType());
                    yield return new WaitForSeconds(0.5f);
                    ResourceItem item = AssetBundleManager.Instance.FindRecourceItem(loadingItem.mCrc);
                    lastYiedTime = System.DateTime.Now.Ticks;

                    CacheResource(loadingItem.mPath, ref item, loadingItem.mCrc, obj, callBackList.Count);

                    for (int j = 0; j < callBackList.Count; j++)
                    {
                        AsyncCallBack callBack = callBackList[j];
                        if (callBack != null && callBack.mDealFinish != null)
                        {
                            callBack.mDealFinish(loadingItem.mPath, obj, callBack.mParme);
                            callBack.mDealFinish = null;
                        }
                        callBack.Reset();
                        mAsyncCallBackPool.Recycle(callBack);
                    }

                    callBackList.Clear();
                    mLoadingAssetDic.Remove(loadingItem.mCrc);

                    loadingItem.Reset();
                    mAsyncLoadResParamPool.Recycle(loadingItem);
                    //Debug.LogError(System.DateTime.Now.Ticks - lastYiedTime);
                    if (System.DateTime.Now.Ticks - lastYiedTime > MAXLOADRESTIME)
                    {
                        yield return null;
                        lastYiedTime = System.DateTime.Now.Ticks;
                        haveYield = true;
                    }
                }
                if (!haveYield || System.DateTime.Now.Ticks - lastYiedTime > MAXLOADRESTIME)
                {
                    yield return null;
                    lastYiedTime = System.DateTime.Now.Ticks;
                }
                yield return null;
            }
        }

        //回收资源（删除资源）
        public override void DestoryResourceItem(ResourceItem item, bool destoryCache = false)
        {

            if (!CanDestoryResourceItem(item, destoryCache))
            {   
                return;
            }

            if (item.m_obj != null)
            {
                item.m_obj = null;
                Resources.UnloadAsset(item.m_obj);
                Resources.UnloadUnusedAssets();
            }
        }

        //资源预加载
        public override void PreloadRes(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                Debug.LogError("path is empty.");
                return;
            }

            uint crc = CRC32.GetCRC32(path);

            ResourceItem _item = GetCacheResourceItem(crc, 0);

            if (_item != null)
                return;

            Object obj;
            _item = AssetBundleManager.Instance.FindRecourceItem(crc);

            if (_item == null)
            {
                Debug.LogError("There is no object to load:" + path);
                return;
            }

            if (_item.m_obj != null)
            {
                obj = _item.m_obj;
            }
            else
            {
                obj = LoadAssetByEditor<Object>(path);
            }

            CacheResource(path, ref _item, crc, obj);

            _item.m_Clear = false;//跳场景不清空这个资源

            ReleaseResource(obj, false);
        }


        /*--------------------------------------私有方法-----------------------------------------------*/

        private T LoadAssetByEditor<T>(string _path) where T : UnityEngine.Object
        {
            T t = null;
#if UNITY_EDITOR
            t = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(_path);
#endif
            return t;
        }

        private Object JudgeLoadType(AsyncLoadResParm loadingItem)
        {
            if (loadingItem.mType == typeof(Sprite))
            {
                return LoadAssetByEditor<Sprite>(loadingItem.mPath);
            }
            else
            {
                return LoadAssetByEditor<Object>(loadingItem.mPath);
            }
        }
    }
}